package com.zbkj.crmeb.merchant.api.controller;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.common.CommonPage;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.taobao.pac.sdk.cp.dataobject.request.MODUAN_ORDER_CREATE.request;
import com.utils.monitor.DingMsgEnum;
import com.utils.monitor.DingTalkMsgUtil;
import com.zbkj.crmeb.front.request.*;
import com.zbkj.crmeb.marketing.response.StoreCouponUserResponse;
import com.zbkj.crmeb.merchant.admin.service.StoreProductStockService;
import com.zbkj.crmeb.merchant.api.request.UpdatePickingProductRequest;
import com.zbkj.crmeb.store.model.CustomsRecord;
import com.zbkj.crmeb.store.model.ExhibitApplication;
import com.zbkj.crmeb.store.model.StoreOrderGroupInfo;
import com.zbkj.crmeb.store.request.StoreOrderSendRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.crmeb.core.common.CommonResult;
import com.common.PageParamRequest;
import com.utils.CrmebUtil;
import com.zbkj.crmeb.front.response.ConfirmOrderResponse;
import com.zbkj.crmeb.front.vo.OrderAgainVo;
import com.zbkj.crmeb.merchant.api.service.MerOrderService;
import com.zbkj.crmeb.store.request.StoreProductReplyAddRequest;
import com.zbkj.crmeb.store.service.ExhibitApplicationService;
import com.zbkj.crmeb.user.service.UserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;

/**
 * @Classname StoreOrderController
 * @Description H5端订单操作
 * @Date 2020/7/4 10:59 上午
 * @Created by stivepeim
 */
@Slf4j
@RestController("MerStoreOrderFrontController")
@RequestMapping("api/front/mer/order")
@Api(tags = "订单")
public class FontOrderController extends ApiBaseController {
    @Autowired
    private UserService userService;
    @Autowired
    private MerOrderService orderService;
    @Autowired
    private StoreProductStockService storeProductStockService;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ExhibitApplicationService exhibitApplicationService;

    /**
     * 根据购物车id确认订单, 并暂存缓存
     * @param cartIds 购物车id集合
     * @return 订单确认结果
     */
    @ApiOperation(value = "确认订单")
    @RequestMapping(value = "/confirm", method = RequestMethod.POST)
    public CommonResult<ConfirmOrderResponse> OrderConForm(@RequestParam String cartIds, @RequestParam boolean isNew, Integer skuId, Integer discountPackageId, HttpServletRequest request) {
        String groupId = null;
        String jsonStr = request.getParameter(Constants.JSON_STR);
        String  leaderId = null;
        if(StringUtils.isNotEmpty(jsonStr)) {
            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
            if(null != jsonObject && null != jsonObject.get("groupId")) {
                groupId = jsonObject.get("groupId").toString();
            }
            if(null != jsonObject && null != jsonObject.get("leaderId")) {
                String str2 = jsonObject.get("leaderId").toString();
                JSONObject object2 = JSONObject.parseObject(str2);
                if(null != object2 && null != object2.get("leaderId")) {
                    leaderId = object2.get("leaderId").toString();
                    if(StringUtils.isNotEmpty(leaderId) && !"0".equals(leaderId)){
                        groupId = storeProductStockService.getGroupIdByProductIdAndLeaderId(leaderId, CrmebUtil.stringToArrayInt(cartIds), getMerId(request), isNew);
                    }
                }

            }
        }

        return CommonResult.success(orderService.confirmOrder(CrmebUtil.stringToArrayInt(cartIds), isNew, getMerId(request), skuId, discountPackageId, groupId));
    }

    /**
     * 生成订单
     * @param key 订单key或者订单id
     * @param request 创建订单参数
     * @return 创建订单后的标识
     */
    @ApiOperation(value = "生成订单")
    @RequestMapping(value = "/create/{key}", method = RequestMethod.POST)
    public CommonResult<Object> createOrder(@PathVariable String key, @Validated @RequestBody OrderCreateRequest orderRequest, HttpServletRequest request) {
        String ip = CrmebUtil.getClientIp(request);
        orderRequest.setMerId(getMerId(request));
        return CommonResult.success(orderService.createOrder(orderRequest, key, ip));
    }

    /**
     * 连连支付再次发起支付
     * @param request 创建订单参数
     * @return 创建订单后的标识
     */
    @ApiOperation(value = "连连支付再次发起支付")
    @RequestMapping(value = "/pay/again", method = RequestMethod.POST)
    public CommonResult<Object> payAgain(@RequestParam String orderId, HttpServletRequest request) {
        if(StringUtils.isEmpty(orderId)){
            throw new CrmebException("数据异常，订单号不能为空！");
        }
        String ip = CrmebUtil.getClientIp(request);
        return CommonResult.success(orderService.getPayToken(orderId, getMerId(request), ip));
    }

    @ApiOperation(value = "提交采购单")
    @RequestMapping(value = "/picking/submit/{key}", method = RequestMethod.POST)
    public CommonResult<Object> submitPickingOrder(@PathVariable String key, @Validated @RequestBody OrderCreateRequest orderRequest, HttpServletRequest request) {
        String ip = CrmebUtil.getClientIp(request);
        orderRequest.setMerId(getMerId(request));
        return CommonResult.success(orderService.submitPickingOrder(orderRequest, key, ip));
    }

    /**
     * 根据参数计算订单价格
     * @param key 订单key
     * @param request 订单参数
     * @return 价格数据
     */
    @ApiOperation(value = "计算价格")
    @RequestMapping(value = "/computed/{key}", method = RequestMethod.POST)
    public CommonResult<Object> computed(@PathVariable String key, @Validated @RequestBody OrderComputedRequest request) {
        return CommonResult.success(orderService.computedOrder(request, key));

    }

    @ApiOperation(value = "计算批采单价格")
    @RequestMapping(value = "picking/computed/{key}", method = RequestMethod.POST)
    public CommonResult<Object> computedPicking(@PathVariable String key, @Validated @RequestBody OrderComputedRequest request) {
        return CommonResult.success(orderService.computedPickingOrder(request, key));

    }

    /**
     * 重复下单
     * @param request 下单参数
     * @return 下单结果
     */
    @ApiOperation(value = "再次下单")
    @RequestMapping(value = "/again", method = RequestMethod.POST)
    public CommonResult<Object> orderAgain(@Validated @RequestBody OrderAgainRequest request) {
        return CommonResult.success(orderService.againOrder(request));
    }

    /**
     * 支付
     * @param orderPayRequest 支付参数
     * @return 支付结果
     */
    @ApiOperation(value = "支付")
    @RequestMapping(value = "/pay", method = RequestMethod.POST)
    public CommonResult<Object> pay(@Validated @RequestBody OrderPayRequest orderPayRequest, HttpServletRequest request) {
        log.info("pay支付结果：{}", JSONObject.toJSONString(orderPayRequest));
        String ip = CrmebUtil.getClientIp(request);
        orderPayRequest.setMerId(getMerId(request));
        return CommonResult.success(orderService.payOrder(orderPayRequest, ip));
    }

    /**
     * 查询订单状态
     * @param orderQueryRequest 查询订单状态参数
     * @return 查询订单状态结果
     */
    @ApiOperation(value = "查询订单状态")
    @RequestMapping(value = "/order/status/get", method = RequestMethod.GET)
    public CommonResult<Object> getOrderStatus(@RequestParam(name = "orderId") String orderId, HttpServletRequest request) {
        OrderQueryRequest orderQueryRequest = new OrderQueryRequest();
        orderQueryRequest.setOrderId(orderId);
        log.info("查询订单状态：{}", JSONObject.toJSONString(orderQueryRequest));
        orderQueryRequest.setMerId(getMerId(request));
        return CommonResult.success(orderService.getOrderStatus(orderQueryRequest));
    }

    /**
     * 订单列表
     * @param type 类型
     * @param searchWord 搜索条件: 订单号/商品名
     * @param pageRequest 分页
     * @return 订单列表
     */
    @ApiOperation(value = "订单列表")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ApiImplicitParams({ @ApiImplicitParam(name = "type", value = "评价等级|1=待付款2=待确认3=待发货4=待收货5=已完成6=售后（退款中，已退款）9=全部（包括1.2.3.4.5.6以及已取消", required = true) })
    public CommonResult<CommonPage<OrderAgainVo>> orderList(@RequestParam(name = "type") Integer type,
                                                            @RequestParam(name = "searchWord",required = false) String searchWord,
                                                            @ModelAttribute PageParamRequest pageRequest) {
        return CommonResult.success(orderService.list(type,searchWord, pageRequest));
    }

    @ApiOperation(value = "批采订单列表")
    @RequestMapping(value = "/picking/list", method = RequestMethod.GET)
    @ApiImplicitParams({ @ApiImplicitParam(name = "type", value = "评价等级|0=待核实1=待付款2=待确认3=待发货4=待收货5=已完成6=售后（退款中，已退款）9=全部（包括1.2.3.4.5.6以及已取消", required = true) })
    public CommonResult<CommonPage<OrderAgainVo>> pickingOrderList(@RequestParam(name = "type") Integer type,
                                                                   @RequestParam(name = "orderNo",required = false) String orderNo,
                                                                   @ModelAttribute PageParamRequest pageRequest) {
        return CommonResult.success(orderService.pickingOrderList(type, orderNo,pageRequest));
    }

    /**
     * 订单详情
     * @param orderId 订单编号
     * @return 订单详情
     */
    @ApiOperation(value = "订单详情")
    @RequestMapping(value = "/detail/{orderId}", method = RequestMethod.GET)
    public CommonResult<Object> orderDetail(@PathVariable String orderId) {
        return CommonResult.success(orderService.detailOrder(orderId));
    }

    /**
     * 订单头部信息
     * @return 查询集合数量
     */
    @ApiOperation(value = "订单头部数量")
    @RequestMapping(value = "/data", method = RequestMethod.GET)
    public CommonResult<Object> orderData() {
        return CommonResult.success(orderService.orderData());
    }

    /**
     * 订单头部信息
     * @return 查询集合数量
     */
    @ApiOperation(value = "批采订单头部数量")
    @RequestMapping(value = "/picking/data", method = RequestMethod.GET)
    public CommonResult<Object> pickingOrderData() {
        return CommonResult.success(orderService.pickingOrderData());
    }

    /**
     * 删除已完成订单
     * @param id String 订单号
     * @return 删除结果
     */
    @ApiOperation(value = "删除订单")
    @RequestMapping(value = "/del", method = RequestMethod.POST)
    public CommonResult<Boolean> delete(@RequestParam Integer id) {
        if (orderService.delete(id)) {
            return CommonResult.success();
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 订单评价
     * @param request StoreProductReplyAddRequest 评论参数
     */
    @ApiOperation(value = "评价订单")
    @RequestMapping(value = "/comment", method = RequestMethod.POST)
    public CommonResult<Boolean> comment(@RequestBody @Validated StoreProductReplyAddRequest request) {
        if (null == request.getOid() || request.getOid() < 1) {
            return CommonResult.validateFailed("订单号参数不能为空");
        }
        if (orderService.reply(request)) {
            return CommonResult.success();
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 订单收货
     * @param id Integer 订单id
     */
    @ApiOperation(value = "订单收货")
    @RequestMapping(value = "/take", method = RequestMethod.POST)
    public CommonResult<Boolean> take(@RequestParam(value = "id") Integer id) {
        if (orderService.take(id)) {
            return CommonResult.success();
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 订单取消
     * @param id Integer 订单id
     */
    @ApiOperation(value = "订单取消")
    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
    public CommonResult<Boolean> cancel(@RequestParam(value = "id") Integer id) {
        if (orderService.cancel(id)) {
            return CommonResult.success();
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 订单退款前验证
     * @return 验证结果
     */
    @ApiOperation(value = "退款订单验证")
    @RequestMapping(value = "/refund/verify", method = RequestMethod.POST)
    public CommonResult<Object> refundVerify(@RequestBody @Validated OrderRefundVerifyRequest request) {
        return CommonResult.success(orderService.refundVerify(request));
    }

    @ApiOperation(value = "填写退货单")
    @RequestMapping(value = "/tracking", method = RequestMethod.POST)
    public CommonResult<Boolean> tracking(@RequestBody @Validated StoreOrderSendRequest request) {
        request.setChannel(5);
        return CommonResult.success(orderService.tracking(request));
    }

    /**
     * 订单退款申请
     * @param request OrderRefundApplyRequest 订单id
     */
    @ApiOperation(value = "订单退款申请")
    @RequestMapping(value = "/refund", method = RequestMethod.POST)
    public CommonResult<Boolean> refundApply(@RequestBody @Validated OrderRefundApplyRequest request) {
        if (orderService.refundApply(request)) {
            return CommonResult.success();
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 查询订单退款理由
     * @return 退款理由
     */
    @ApiOperation(value = "订单退款理由")
    @RequestMapping(value = "/refund/reason", method = RequestMethod.GET)
    public CommonResult<Object> refundReason() {
        return CommonResult.success(orderService.getRefundReason());
    }

    /**
     * 根据订单号查询物流信息
     * @param orderId 订单号
     * @return 物流信息
     */
    @ApiOperation(value = "物流信息查询")
    @RequestMapping(value = "/express/{orderId}", method = RequestMethod.GET)
    public CommonResult<Object> getExpressInfo(@PathVariable String orderId) {
        return CommonResult.success(orderService.expressOrder(orderId));
    }

    @ApiOperation(value = "待评价商品信息查询")
    @RequestMapping(value = "/product", method = RequestMethod.POST)
    public CommonResult<Object> getOrderProductForReply(@Validated @RequestBody GetProductReply request) {
        return CommonResult.success(orderService.getReplyProduct(request));
    }
    @ApiOperation(value = "积分配置查询")
    @RequestMapping(value = "/enableIntegral", method = RequestMethod.GET)
    public CommonResult<Object> enableIntegral() {
        return CommonResult.success(orderService.enableIntegral());
    }

    @ApiOperation(value = "修改订单地址")
    @PutMapping(value = "/address")
    public CommonResult<Object> updateOrderAddress(@Validated @RequestBody UpdateOrderAddressRequest request) {
        return orderService.updateOrderAddress(request) ? CommonResult.success() : CommonResult.failed();
    }

    @ApiOperation(value = "修改自提手机号")
    @PutMapping(value = "/toPhone")
    public CommonResult<Object> updateOrderToPhone(@RequestParam(value = "id") @ApiParam(value = "订单id",required = true) Integer id,
                                                   @RequestParam(value = "toPhone") @ApiParam(value = "自提手机号",required = true) String toPhone) {
        return orderService.updateOrderToPhone(id,toPhone) ? CommonResult.success() : CommonResult.failed();
    }

    @ApiOperation(value = "确认订单可用优惠券")
    @RequestMapping(value = "/confirmCoupons", method = RequestMethod.POST)
    public CommonResult<List<StoreCouponUserResponse>> listConfirmCoupons(@ApiParam(value = "cartIds") @RequestParam String cartIds,
                                                                          @ApiParam(value = "isNew" ) @RequestParam boolean isNew,
                                                                          HttpServletRequest request) {
        return CommonResult.success(orderService.listConfirmCoupons(CrmebUtil.stringToArrayInt(cartIds), isNew, getMerId(request)));
    }

    @ApiOperation(value = "修改待核实批采订单商品数量")
    @PutMapping(value = "/picking/product/update")
    public CommonResult<Object> updatePickingProduct(@Validated @RequestBody UpdatePickingProductRequest request) {
        return orderService.updatePickingProduct(request) ? CommonResult.success() : CommonResult.failed();
    }

    /**
     * 查询展会报名表信息
     * @param id Integer
     * @author Mr.Zhang
     * @since 2020-05-27
     */
    @ApiOperation(value = "详情")
    @GetMapping("/exhibit/info/{id}")
    public CommonResult<ExhibitApplication> infoExhibitApplication(@PathVariable Integer id) {
        Integer userId = userService.getUserIdException();
        if (userId == null || userId == 0) {
            DingTalkMsgUtil.sendMsg(DingMsgEnum.OTHER,"未登录访问海报，"+new Date());
            return CommonResult.failed("请登录后再提交数据");
        }
        DingTalkMsgUtil.sendMsg(DingMsgEnum.OTHER,userId+"访问海报，"+new Date());
        ExhibitApplication exhibitApplication = exhibitApplicationService.getOne(Wrappers.<ExhibitApplication>lambdaQuery()
                .eq(ExhibitApplication::getCreateUserUid, String.valueOf(userId))
                .last("limit 1"));
        if(null == exhibitApplication){
            return CommonResult.failed();
        }
        if(StringUtils.isNotEmpty(exhibitApplication.getBusinessName())){
            exhibitApplication.setBusinessNameList(CrmebUtil.stringToArrayStrRegex(exhibitApplication.getBusinessName(), "，" ));
        }
        if(StringUtils.isNotEmpty(exhibitApplication.getPreferenceName())){
            exhibitApplication.setPreferenceNameList(CrmebUtil.stringToArrayStrRegex(exhibitApplication.getPreferenceName(), "，"));
        }
        if(StringUtils.isNotEmpty(exhibitApplication.getPurchaseChannel())){
            exhibitApplication.setPurchaseChannelList(CrmebUtil.stringToArrayStrRegex(exhibitApplication.getPurchaseChannel(), "，"));
        }
        return CommonResult.success(exhibitApplication);
    }

    /**
     * 新增展会报名表
     * @author Mr.Zhang
     * @since 2020-05-27
     */
    @ApiOperation(value = "新增")
    @PostMapping("/exhibit/save")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> saveExhibitApplication(@RequestBody @Validated ExhibitApplication exhibitApplication,
                                                       HttpServletRequest request) {
        String result = exhibitApplicationService.saveExhibitApplication(exhibitApplication, getMerId(request));
        if(null != result){
            return CommonResult.failed(result);
        }
        return CommonResult.success();
    }

    /**
     * 修改展会报名表
     * @param exhibitApplication 修改参数
     * @author Mr.Zhang
     * @since 2020-05-27
     */
    @ApiOperation(value = "修改")
    @PutMapping("/exhibit/update")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> updateExhibitApplication(@RequestBody @Validated ExhibitApplication exhibitApplication) {

        boolean update = exhibitApplicationService.updateById(exhibitApplication);

        return update ? CommonResult.success() : CommonResult.failed();
    }

}
